
import audioLoader from 'audio-loader';
import { exec } from 'child_process';
import fs from 'fs';
import path from 'path';
import { JsonFileManager } from './utils.js';

class AudioPlayer {
  constructor(playedHistory = [], isLoopEnabled = false, replayUrl, uid, dodge, volume) {
    this.currentPlayer = null;
    this.durationCache = new Map();
    this.playedHistory = [...playedHistory];
    this.isLoopEnabled = isLoopEnabled;
    this.isPlayAll = false;
    this.isPlaying = false;
    this.dodge = dodge;
    this.volume = volume;
    this.remoteAudioQueue = []; // 远程音频队列
    this.apiUrl = `${replayUrl}/getAudio?uid=${uid}`; // 替换为实际API地址
    this.checkInterval = 5000; // 远程检查间隔(ms)

    this.dataJsonManager = new JsonFileManager('./data.json');
    this.maxRetryCount = 3;
    this.currentRetryCount = 0;
  }

  async getAudioDuration(audioPath) {
    if (this.durationCache.has(audioPath)) {
      return this.durationCache.get(audioPath);
    }
    try {
      const audio = await audioLoader(audioPath);
      const duration = Math.ceil(audio.duration * 1000);
      this.durationCache.set(audioPath, duration);
      return duration;
    } catch (err) {
      console.error(`无法获取 ${path.basename(audioPath)} 时长:`, err.message);
      return 3000;
    }
  }

  savePlayData() {
    this.dataJsonManager.update(old => ({ ...old, playList: this.playedHistory }));
  }

  async getServer() {
    return new Promise((resolve, reject) => {
      fetch(this.apiUrl, {
        headers: {
          "accept-language": "zh-CN,zh;q=0.9",
          "content-type": "application/json",
        },
        method: "GET",
        mode: "cors",
      })
        .then(async response => {
          const reader = response.body.getReader();
          const decoder = new TextDecoder();
          let result = '';

          while (true) {
            const { done, value } = await reader.read();
            if (done) break;
            result += decoder.decode(value);
          }

          const parsedResult = JSON.parse(result);

          resolve(parsedResult);
        })
        .catch(error => {
          reject(error);
        });
    });
  }

  async checkRemoteAudio() {
    try {
      console.log(this.apiUrl);

      const response = await this.getServer();

      const { count, url } = response;

      if (count > 0 && url) {
        this.remoteAudioQueue.push(url);
        console.log('发现远程音频:', url);
      }
    } catch (err) {
      console.error('获取远程音频失败:', err);
    }
  }
  async getNextAudio(folderPath) {
    // 优先播放远程队列中的音频
    if (this.remoteAudioQueue.length > 0) {
      return this.remoteAudioQueue.shift()[0];
    }

    // 本地文件逻辑
    let files = fs.readdirSync(folderPath)
      .filter(file => ['.mp3', '.wav'].includes(path.extname(file).toLowerCase()));

    if (files.length === 0) throw new Error('未找到音频文件');

    if (this.playedHistory.length > 0) {
      files = files.filter(file => !this.playedHistory.includes(file));
      if (files.length === 0) {
        if (this.isLoopEnabled) {
          console.log('所有文件已播放，重置历史记录');
          this.playedHistory = [];
          files = fs.readdirSync(folderPath)
            .filter(file => ['.mp3', '.wav'].includes(path.extname(file).toLowerCase()));
        } else {
          this.isPlayAll = true;
          throw new Error('PLAY_ALL_COMPLETED');
        }
      }
    }

    const selectedFile = files[Math.floor(Math.random() * files.length)];
    return path.join(folderPath, selectedFile);
  }


  getRandomAudioFile(folderPath) {
    let files = fs.readdirSync(folderPath)
      .filter(file => ['.mp3', '.wav'].includes(path.extname(file).toLowerCase()));

    if (files.length === 0) throw new Error('未找到音频文件');

    if (this.playedHistory.length > 0) {
      files = files.filter(file => !this.playedHistory.includes(file));
      if (files.length === 0) {
        if (this.isLoopEnabled) {
          console.log('所有文件已播放，重置历史记录');
          this.playedHistory = [];
          files = fs.readdirSync(folderPath)
            .filter(file => ['.mp3', '.wav'].includes(path.extname(file).toLowerCase()));
        } else {
          this.isPlayAll = true;
          console.log('所有文件已播放完毕');
          throw new Error('PLAY_ALL_COMPLETED');
        }
      }
    }

    const selectedFile = files[Math.floor(Math.random() * files.length)];
    return path.join(folderPath, selectedFile);
  }

  async playAudio(audioPath) {
    return new Promise((resolve, reject) => {
      if (this.currentPlayer) this.currentPlayer.kill();
      let volume = this.volume == '' ? 0 : this.volume;

      if (this.dodge != '') {
        exec(`nircmd.exe setappvolume  "${this.dodge}" ${volume}`);
      }

      this.currentPlayer = exec(`"cmdmp3.exe" "${audioPath}"`, (error) => {
        if (error) {
          console.error('播放错误:', error);
          exec(`nircmd.exe setappvolume  "${this.dodge}" 1`);
          reject(error);
        } else {
          exec(`nircmd.exe setappvolume  "${this.dodge}" 1`);
          resolve();
        }
      });
    });
  }

  async playNext(folderPath) {
    if (!this.isPlaying) return;

    try {
      // 定期检查远程音频
      if (Date.now() - (this.lastCheckTime || 0) > this.checkInterval) {

      }
      await this.checkRemoteAudio();
      this.lastCheckTime = Date.now();

      const nextAudio = await this.getNextAudio(folderPath);

      console.log('正在播放:', path.basename(nextAudio));

      await this.playAudio(nextAudio);

      // 仅本地文件记录播放历史
      if (!nextAudio.startsWith('http')) {
        this.playedHistory.push(path.basename(nextAudio));
        this.savePlayData();
      }

      this.currentRetryCount = 0;
      this.playNext(folderPath);
    } catch (err) {
      if (err.message === 'PLAY_ALL_COMPLETED') {
        this.stop();
      } else {
        console.error('播放出错:', err.message);
        this.currentRetryCount++;
        const delayTime = this.currentRetryCount * 1000;

        if (this.currentRetryCount <= this.maxRetryCount) {
          console.log(`正在重试 (${this.currentRetryCount}/${this.maxRetryCount})...`);
          setTimeout(() => this.playNext(folderPath), delayTime);
        } else {
          console.log('达到最大重试次数，跳过当前文件');
          this.currentRetryCount = 0;
          setTimeout(() => this.playNext(folderPath), delayTime);
        }
      }
    }
  }

  start(folderPath) {
    this.isPlaying = true;
    this.isPlayAll = false;
    this.currentRetryCount = 0;
    this.playNext(folderPath).catch(console.error);
  }

  stop() {
    this.isPlaying = false;
    if (this.currentPlayer) {
      this.currentPlayer.kill();
      this.currentPlayer = null;
    }
  }
}

export function runPlayer(config) {
  const { audioFolder, playedHistory, isLoopEnabled, replayUrl, uid, dodge, volume } = config;

  const player = new AudioPlayer(playedHistory, isLoopEnabled, replayUrl, uid, dodge, volume);
  player.start(audioFolder);

  return player;
}
